package org.csu.mall.service.impl;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import oracle.jrockit.jfr.parser.ChunkParser;
import org.apache.commons.lang3.StringUtils;
import org.csu.mall.common.CONSTANT;
import org.csu.mall.common.ResponseCode;
import org.csu.mall.common.UniformResponse;
import org.csu.mall.entity.Account;
import org.csu.mall.entity.Category;
import org.csu.mall.entity.Commodity;
import org.csu.mall.entity.MerchantOrder;
import org.csu.mall.persistence.AccountMapper;
import org.csu.mall.persistence.CategoryMapper;
import org.csu.mall.persistence.CommodityMapper;
import org.csu.mall.persistence.MerchantOrderMapper;
import org.csu.mall.service.ICategoryService;
import org.csu.mall.service.ICommodityService;
import org.csu.mall.util.CodeUtil;
import org.csu.mall.util.DateUtil;
import org.csu.mall.util.PropertiesUtil;
import org.csu.mall.util.QiniuUtil;
import org.csu.mall.vo.CartCommodityVO;
import org.csu.mall.vo.CategoryVO;
import org.csu.mall.vo.CommodityListVO;
import org.csu.mall.vo.CommodityVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service("commodityService")
public class ICommodityServiceImpl implements ICommodityService {

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private ICategoryService categoryService;

    @Autowired
    private MerchantOrderMapper merchantOrderMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<CommodityVO> getCommodityDetail(String itemId) {
        if(StringUtils.isBlank(itemId)){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDescription());
        }
        Commodity commodity = commodityMapper.selectOne(Wrappers.<Commodity>query().eq("item_id", itemId));
        if(commodity == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.COMMODITY_NOT_EXIST.getCode(), ResponseCode.COMMODITY_NOT_EXIST.getDescription());
        }
        if(commodity.getStatus() == CONSTANT.CommodityStatus.NO_SALE.getCode()
                || commodity.getStatus() == CONSTANT.CommodityStatus.OUT_SALE.getCode()){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.COMMODITY_SALE_OUT.getCode(), ResponseCode.COMMODITY_SALE_OUT.getDescription());
        }
        CommodityVO commodityVO = this.entityToVO(commodity);
        return UniformResponse.createForSuccess(ResponseCode.SUCCESS.getDescription(), commodityVO);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<CommodityListVO> getCommodityList(String categoryId, String keyword, int pageNum, int pageSize, String orderBy, int source, int status) {
        Page<Commodity> result = new Page<>();
        result.setCurrent(pageNum);
        result.setSize(pageSize);

        QueryWrapper<Commodity> queryWrapper = new QueryWrapper<>();
        //增加类别查询
        if(StringUtils.isNotBlank(categoryId)){
            List<CategoryVO> categoryVOList = categoryService.getAllChildrenCategory(categoryId).getData();
            List<String> categoryIdList = Lists.newArrayList();
            for(CategoryVO categoryVO: categoryVOList){
                categoryIdList.add(categoryVO.getCategoryId());
            }
            if(CollectionUtils.isEmpty(categoryIdList)){
                return UniformResponse.createForErrorMessage("无该类别的商品");
            }
            queryWrapper.in("category_id", categoryIdList);
        }
        //增加模糊查询
        if(StringUtils.isNotBlank(keyword)){
            keyword = new StringBuilder().append("%").append(keyword).append("%").toString();
            queryWrapper.like("item_name", keyword);
        }

        //增加商品平台检索
        if(CONSTANT.CommoditySource.ALL_SALE.getCode()!= source){
            queryWrapper.eq("source", source);
        }

        //增加商品状态检索
        if(CONSTANT.CommodityStatus.ON_SALE.getCode() == status){
            queryWrapper.ge("status", status);
        }else{
            queryWrapper.eq("status", status);
        }

        //排序
        if(StringUtils.isNotBlank(orderBy)){
            if(CONSTANT.CommodityListOrderBy.PRICE_ASC_DESC.contains(orderBy)){
                String[] orderByString = orderBy.split("_");
                if(StringUtils.equals(orderByString[1], "asc")){
                    queryWrapper.orderByAsc(orderByString[0]);
                }else if(StringUtils.equals(orderByString[1], "desc")){
                    queryWrapper.orderByDesc(orderByString[0]);
                }
            }
        }

        result = commodityMapper.selectPage(result, queryWrapper);
        CommodityListVO commodityListVO = this.pageToVO(result, orderBy);
        return UniformResponse.createForSuccess(ResponseCode.SUCCESS.getDescription(), commodityListVO);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<String> releaseCommodity(Account account, String address, Commodity commodity) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        account = accountMapper.selectById(account.getUserId());
        if(CONSTANT.Role.CUSTOMER == account.getRole()){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.PERMISSION_DENIED.getCode(), ResponseCode.PERMISSION_DENIED.getDescription());
        }
        if(CONSTANT.Role.ADMIN == account.getRole()){
            commodity.setSource(CONSTANT.CommoditySource.OFFICIAL_SALE.getCode());
        }
        if(CONSTANT.Role.AUTHENTICATION == account.getRole()){
            commodity.setSource(CONSTANT.CommoditySource.PERSONAL_SALE.getCode());
        }
        //拼接商品id
        List<String> parentIdList = Lists.newArrayList();
        //加入商品类型
        Category category = categoryMapper.selectOne(Wrappers.<Category>query().eq("category_id", commodity.getCategoryId()));
        parentIdList.add(StringUtils.upperCase(commodity.getCategoryId()));
        while(category != null){
            String parentId = category.getParentId();
            parentIdList.add(0, StringUtils.upperCase(parentId));
            category = categoryMapper.selectOne(Wrappers.<Category>query().eq("category_id", parentId));
        }
        //加入商品平台
        parentIdList.add(Integer.toString(account.getRole()));
        //加入商品序号
        int count = commodityMapper.selectCount(
                Wrappers.<Commodity>query().eq("category_id", commodity.getCategoryId())) + 1;
        String itemId;
        while (true){
            parentIdList.add(Integer.toString(count));
            itemId = StringUtils.join(parentIdList, "-", 0, parentIdList.size());
            int row = commodityMapper.selectCount(Wrappers.<Commodity>query().eq("item_id", itemId));
            if(row == 0){
                break;
            }
            parentIdList.remove(parentIdList.size()-1);
            count++;
        }
        commodity.setItemId(itemId);
        //设置图片
        String imgAddress = commodity.getImage();
        if(StringUtils.isNotBlank(imgAddress)){
            String baseAddress = "D:\\img";
            imgAddress = new StringBuilder(baseAddress).append("\\").append(imgAddress).toString();
            String[] str = imgAddress.split("\\\\");
            String img = new StringBuilder().append(commodity.getItemId()).append(str[str.length - 1]).toString();
            commodity.setImage(img);
            QiniuUtil.upload(imgAddress, commodity.getImage());
        }
        //
        commodity.setStatus(CONSTANT.CommodityStatus.ON_SALE.getCode());
        commodity.setCreateTime(LocalDateTime.now());
        commodity.setUpdateTime(LocalDateTime.now());
        commodityMapper.insert(commodity);
        //插入发布订单信息
        MerchantOrder merchantOrder = new MerchantOrder();
        merchantOrder.setOrderId(CodeUtil.createOrderId());
        merchantOrder.setOrderName(commodity.getItemName());
        merchantOrder.setItemId(itemId);
        merchantOrder.setItemName(commodity.getItemName());
        merchantOrder.setItemNumber(commodity.getStock());
        merchantOrder.setUnitPrice(commodity.getPrice());
        merchantOrder.setTotalPrice(commodity.getStock() * commodity.getPrice());
        merchantOrder.setOrderSource(commodity.getSource());
        merchantOrder.setMerchantId(account.getUserId());
        merchantOrder.setPhoneNumber(account.getPhoneNumber());
        merchantOrder.setOrderState(CONSTANT.MerchantOrderStatus.ORDER_ON_SALE.getCode());
        merchantOrder.setAddress(address);
        merchantOrder.setCreateTime(LocalDateTime.now());
        merchantOrder.setUpdateTime(LocalDateTime.now());
        merchantOrderMapper.insert(merchantOrder);
        return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<String> updateCommodity(Account account, Commodity commodity) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        if(CONSTANT.Role.CUSTOMER == account.getRole()){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.PERMISSION_DENIED.getCode(), ResponseCode.PERMISSION_DENIED.getDescription());
        }
        commodity.setUpdateTime(LocalDateTime.now());
        int row = commodityMapper.update(commodity, Wrappers.<Commodity>query().eq("item_id", commodity.getItemId()));
        if(row > 0){
            return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
        }
        return UniformResponse.createForErrorCodeMessage(ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDescription());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<String> cancelCommodity(Account account, String itemId) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        if(CONSTANT.Role.CUSTOMER == account.getRole()){
            return UniformResponse.createForErrorCodeMessage(ResponseCode.PERMISSION_DENIED.getCode(), ResponseCode.PERMISSION_DENIED.getDescription());
        }
        int row = commodityMapper.delete(Wrappers.<Commodity>query().eq("item_id", itemId));
        if(row >0){
            return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
        }
        return UniformResponse.createForErrorCodeMessage(ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDescription());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<CartCommodityVO> purchaseCommodity(String itemId, Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        Commodity commodity = commodityMapper.selectOne(Wrappers.<Commodity>query().eq("item_id", itemId));
        CartCommodityVO cartCommodityVO = new CartCommodityVO();
        cartCommodityVO.setItemId(itemId);
        cartCommodityVO.setItemName(commodity.getItemName());
        cartCommodityVO.setQuantity(1);
        cartCommodityVO.setSource(commodity.getSource());
        cartCommodityVO.setPrice(commodity.getPrice());
        cartCommodityVO.setTotalPrice(commodity.getPrice());
        cartCommodityVO.setStatus(commodity.getStatus());
        cartCommodityVO.setImage(commodity.getImage());
        cartCommodityVO.setStar(commodity.getStar());
        cartCommodityVO.setCreateTime(DateUtil.localDateTimeToString(commodity.getCreateTime()));
        cartCommodityVO.setUpdateTime(DateUtil.localDateTimeToString(commodity.getUpdateTime()));
        cartCommodityVO.setImageHost(PropertiesUtil.getProperty("image.server.url"));

        return UniformResponse.createForSuccess(cartCommodityVO);
    }

    @Override
    public UniformResponse<String> addCommodityImage(String itemId, String imgAddress, Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }

        if(account.getRole() == CONSTANT.Role.CUSTOMER){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.PERMISSION_DENIED.getCode(), ResponseCode.PERMISSION_DENIED.getDescription());
        }

        Commodity commodity = commodityMapper.selectOne(Wrappers.<Commodity>query().eq("item_id", itemId));
        if(commodity == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.COMMODITY_NOT_EXIST.getCode(), ResponseCode.COMMODITY_NOT_EXIST.getDescription());
        }
        String subImages = commodity.getSubImage();
        String[] str = imgAddress.split("\\\\");
        String img = new StringBuilder().append(commodity.getItemId()).append(str[str.length - 1]).append(str.length).toString();
        QiniuUtil.upload(imgAddress, img);
        if(StringUtils.isNotBlank(subImages)){
            img = new StringBuilder().append(subImages).append(";").append(img).toString();
        }
        commodity.setSubImage(img);
        int row = commodityMapper.updateById(commodity);
        if(row == 0){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDescription());
        }
        return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
    }

    private CommodityVO entityToVO(Commodity commodity){
        CommodityVO commodityVO = new CommodityVO();

        commodityVO.setId(commodity.getId());
        commodityVO.setItemId(commodity.getItemId());
        commodityVO.setCategoryId(commodity.getCategoryId());
        commodityVO.setSource(commodity.getSource());
        commodityVO.setItemName(commodity.getItemName());
        commodityVO.setPrice(commodity.getPrice());
        commodityVO.setStock(commodity.getStock());
        commodityVO.setStatus(commodity.getStatus());
        commodityVO.setDescription(commodity.getDescription());
        commodityVO.setSubImage(commodity.getSubImage());
        commodityVO.setImage(commodity.getImage());
        commodityVO.setStar(commodity.getStar());
        //新增子图片
        List<String> subImageList = Lists.newArrayList();
        if(StringUtils.isNotBlank(commodity.getSubImage())){
            String[] images = commodity.getSubImage().split(";");
            for(String img: images){
                subImageList.add(img);
            }
        }
        commodityVO.setSubImages(subImageList);
        //新增或修改属性
        commodityVO.setCreateTime(DateUtil.localDateTimeToString(commodity.getCreateTime()));
        commodityVO.setUpdateTime(DateUtil.localDateTimeToString(commodity.getUpdateTime()));
        commodityVO.setImageHost(PropertiesUtil.getProperty("image.server.url"));
        Category category = categoryMapper.selectOne(
                Wrappers.<Category>query().eq("category_id", commodity.getCategoryId()));
        commodityVO.setCategoryName(category.getCategoryName());
        return commodityVO;
    }

    private CommodityListVO pageToVO(Page<Commodity> result, String orderBy){
        CommodityListVO commodityListVO = new CommodityListVO();
        commodityListVO.setPageNum(result.getCurrent());
        commodityListVO.setPageSize(result.getSize());
        commodityListVO.setOrderBy(orderBy);
        commodityListVO.setStartRow(1);
        commodityListVO.setEndRow(result.getPages());
        commodityListVO.setTotal(result.getTotal());
        commodityListVO.setPages(result.getPages());
        List<Commodity> commodityList = result.getRecords();
        List<CommodityVO> commodityVOList = Lists.newArrayList();
        for(Commodity commodity: commodityList){
            commodityVOList.add(this.entityToVO(commodity));
        }
        commodityListVO.setCommodityVOS(commodityVOList);
        commodityListVO.setFirstPage(1l);
        commodityListVO.setPrePage(result.getCurrent() - 1);
        commodityListVO.setNextPage(result.getCurrent() + 1);
        commodityListVO.setIsFirstPage(result.getCurrent() == 1);
        commodityListVO.setIsLastPage(result.getCurrent() == result.getPages());
        commodityListVO.setHasPreviousPage(result.getCurrent() > 1);
        commodityListVO.setHasNextPage(result.getCurrent() < result.getPages());
        commodityListVO.setImageHost(PropertiesUtil.getProperty("image.server.url"));
        return commodityListVO;
    }
}
